package com.dxl.service.account;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.dxl.bean.session.Session;
import com.dxl.common.consts.SysConsts;
import com.dxl.common.enums.State;
import com.dxl.common.id.UUIDGenerator;
import com.dxl.common.model.Page;
import com.dxl.common.model.RespData;
import com.dxl.common.utils.MD5;
import com.dxl.common.utils.Utils;
import com.dxl.dao.account.AccountDao;
import com.dxl.dao.account.FunctionDao;
import com.dxl.entity.account.Account;
import com.dxl.entity.account.AccountRole;
import com.dxl.service.common.BaseService;

@Service
@Transactional
public class AccountService extends BaseService {
	private static final Logger LOG = Logger.getLogger(AccountService.class);
	@Autowired
	private AccountDao accountDao;
	@Autowired
	private FunctionDao functionDao;
	
	public RespData save(Account account) {
		Account srcAccount;
		if (Utils.isNotBlank(account.getId())) {
			srcAccount = this.get(Account.class, account.getId());
			srcAccount.setAccount(account.getAccount());
			if (!SysConsts.SIX_STAR.equals(account.getPassword())) {
				srcAccount.setPassword(MD5.crypt(account.getPassword()));
			}
			srcAccount.setName(account.getName());
			srcAccount.setMobile(account.getMobile());
			srcAccount.setEmail(account.getEmail());
			srcAccount.setState(account.getState());
		} else {
			Map<String, Object> params = new HashMap<String, Object>();
			params.put("account", account.getAccount());
			if (this.count(Account.class, params) > 0) {
				return RespData.instance(RespData.FAIL, "账户已经存在！");
			}
			srcAccount = account;
			srcAccount.setPassword(MD5.crypt(account.getPassword()));
		}
		super.save(srcAccount);
		Map<String, Object> params = new HashMap<String, Object>(), values = new HashMap<String, Object>();
		values.put("state", srcAccount.getState());
		params.put("accountId", srcAccount.getId());
		this.update(AccountRole.class, params, values);
		return RespData.instance(RespData.SUCCESS, srcAccount.getId());
	}
	
	public RespData del(String[] ids) {
		if (Utils.isEmpty(ids)) {
			return RespData.instance(RespData.SUCCESS);
		} else {
			try {
				this.del(Account.class, ids);
				Map<String, Object> params = new HashMap<String, Object>();
				for (String id : ids) {
					params.put("accountId", id);
					this.del(AccountRole.class, params);
				}
				return RespData.instance(RespData.SUCCESS);
			} catch (Exception e) {
				LOG.error(e.getMessage(), e);
				return RespData.instance(RespData.FAIL);
			}
		}
	}
	
	public RespData state(String[] ids, Integer state) {
		if (Utils.isEmpty(ids)) {
			return RespData.instance(RespData.SUCCESS);
		} else {
			try {
				Map<String, Object> params = new HashMap<String, Object>(), values = new HashMap<String, Object>();
				values.put("state", state);
				this.update(Account.class, ids, values);
				for (String id : ids) {
					params.put("accountId", id);
					this.update(AccountRole.class, params, values);
				}
				return RespData.instance(RespData.SUCCESS);
			} catch (Exception e) {
				LOG.error(e.getMessage(), e);
				return RespData.instance(RespData.FAIL);
			}
		}
	}
	
	public Page<Account> list(String keyword, Integer state, Integer page, Integer rows) {
		return accountDao.list(keyword, state, page, rows);
	}
	
	public void authorize(String accountId, String[] roleIds) {
		if (Utils.isBlank(accountId)) {
			return;
		}
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("accountId", accountId);
		this.del(AccountRole.class, params);
		AccountRole accountRole;
		if (Utils.isNotEmpty(roleIds)) {
			for (String rid : roleIds) {
				accountRole = new AccountRole();
				accountRole.setRoleId(rid);
				accountRole.setAccountId(accountId);
				super.save(accountRole);
			}
		}
	}
	
	public Session login(String sessionId, String account, String password) {
		Session session = null;
		if (Utils.isNotBlank(sessionId)) {
			Object s = this.cache.get(sessionId.trim());
			if (Utils.isNotNull(s)) {
				session = (Session) s;
			}
		} else if (Utils.isNotBlank(account) && Utils.isNotBlank(password)) {
			Account acct = this.accountDao.list(account, password, State.ACTIVE);
			if (Utils.isNotNull(acct)) {
				acct.setErrLoginCount(0);
				accountDao.save(acct);
				acct.setPassword(SysConsts.SIX_STAR);
				
				session = new Session();
				session.setId(UUIDGenerator.get().genUUID());
				session.setAccount(acct);
				session.setFunctions(this.functionDao.listFunctions(acct.getId(), State.ACTIVE));
			} else {
				acct.setErrLoginCount(Utils.isNull(acct.getErrLoginCount()) ? 1 : acct.getErrLoginCount() + 1);
				accountDao.save(acct);
			}
		}
		if (Utils.isNotNull(session)) {
			// 刷新会话
			this.cache.set(session.getId(), session, 1800);
		}
		return session;
	}
	
	public void logout(String sessionId) {
		if (Utils.isNotBlank(sessionId)) {
			this.cache.remove(sessionId.trim());
		}
	}
	
	public boolean hasPermission(String sessionId, String... functions) {
		if (Utils.isBlank(sessionId)) {
			return false;
		}
		Session session = (Session) this.cache.get(sessionId);
		if (Utils.isNull(session)) {
			return false;
		}
		Set<String> functionCodes = session.getFunctionCodes();
		if (Utils.isNotEmpty(functions) && Utils.isEmpty(functionCodes)) {
			return false;
		} else if (Utils.isNotEmpty(functions) && Utils.isNotEmpty(functionCodes)) {
			for (String function : functions) {
				if (Utils.isNotBlank(function) && !functionCodes.contains(function)) {
					return false;
				}
			}
		}
		return true;
	}
}
